package cn.com.captureNetPacket.voice;

import java.util.Date;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;

import cn.com.captureNetPacket.CaptureNetPacketService;
import cn.com.captureNetPacket.model.DeviceInfo;
import cn.com.captureNetPacket.model.SignallingInfo;
import cn.com.captureNetPacket.record.WavFileInfo;
import cn.com.captureNetPacket.util.RedisConfig;
import cn.com.captureNetPacket.util.RedisConfig2;
import cn.com.captureNetPacket.util.Tools;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Data
@Slf4j
/**
 * 本类主要是收集到信息后发送数据流和信令信息的作用
 * @author ASUS:augustWei
 *
 */
public class VoiceInfoPush extends Thread{
	 private SignallingInfo signallingInfo;
	 DeviceInfo deviceInfo=null;
	 private WavFileInfo wavFileInfo=null;
	private boolean stopThread;
	private long sleepTime=1000;
	byte[] positiveRealTimeData;
	private ObjectMapper objMap=new ObjectMapper();
//	byte[] reverseRealTimeData;
	// 保留一起发送的数据
	byte[] positiveRetainData;
//	byte[] reverseRetainData;
	private String pushSeesionId;
	private Object lockObj=new Object();
	public VoiceInfoPush(SignallingInfo signallingInfo) {
		this.signallingInfo= signallingInfo;
	}
     @Override
	   	public void run() {
	   		try {
	   			log.debug(" Analysis thread {} starting   !!! ",signallingInfo.toStringPart());
	   			 initAnalysis();
	   					while(!stopThread) {
	   						try {
//	   							log.debug("Analysis thread {} runing   !!! ",signallingInfo.toStringPart());
	   							pushData();
	   							Thread.sleep(sleepTime);
	   						} catch (Exception e) {
	   							 log.error("run Exception Error {}",e);
	   							e.printStackTrace();
	   						}
	   					}
	   					// 结束时将信令和随路信息解析出来发送出去。
	   					endAnalysis();
	   		}catch (Exception e) {
	   			log.error(" thread Exception {} Exception   !!!  ",signallingInfo.toStringPart(),e);
	   			e.printStackTrace();
	   		}
	   		log.debug("Analysis thread {} stoping   !!! ",signallingInfo.toStringPart());
	   		 
	   	}

	private void endAnalysis() {
		CaptureNetPacketService.getIatConfig().endSession(pushSeesionId,signallingInfo);
//		log.debug("VoiceInfoPush endAnalysis signallingInfo: {}",signallingInfo);
		
	}
	
	/**
	 * 控制速率和发送包大小
	 */
	
	private static int rate=8000;
	private void pushData() {
		if(deviceInfo==null)return;
		if(deviceInfo.getDeviceNumber()==null)return;
		byte[][] firstGroupBuffer=null,reverseGroupBuffer=null;
		int groupCount=0;
		synchronized (lockObj) {
		if(positiveRetainData ==null)return ;

//		int sendLehgth=0;
//		sendLehgth=firstRetainData.length;
//		// 取数据小的
//		if(sendLehgth>reverseRetainData.length)
//		{
//			sendLehgth=reverseRetainData.length;
//		}
		// 分多少组
		
		groupCount= positiveRetainData.length/rate;
		// 说明没数据
		if(groupCount==0)return ;
		log.debug("VoiceInfoPush sessionid: {} DeviceNumber: {} sendData  firstRetainData size : {}  rate: {} ,分组: {}----------------------------------------》》》 signallingInfo: {}",pushSeesionId,deviceInfo.getDeviceNumber(), positiveRetainData.length,rate,groupCount,signallingInfo.toStringPart());
//		log.debug("VoiceInfoPush sendData -----------------------------------------------------》》》 signallingInfo: {}",signallingInfo.toStringPart());
		  firstGroupBuffer=Tools.oneDimensional2TwoDimensional(positiveRetainData, rate,groupCount);
//		  reverseGroupBuffer=Tools.oneDimensional2TwoDimensional(reverseRetainData, rate,groupCount);
		
		
		// 剩余部分保留
		byte[] byteTemp=new byte[positiveRetainData.length-(groupCount*rate)];
		System.arraycopy(positiveRetainData, groupCount*rate, byteTemp, 0, positiveRetainData.length-(groupCount*rate));
		positiveRetainData =byteTemp;
//		// 保存剩余反方向
//		byteTemp=new byte[reverseRetainData.length-(groupCount*rate)];
//		System.arraycopy(reverseRetainData, groupCount*rate, byteTemp, 0, reverseRetainData.length-(groupCount*rate));
//		reverseRetainData=byteTemp;
		}
		
		
//		log.debug("VoiceInfoPush sendData  firstRetainData size : {}  rate: {} ,分组: {}---->>>>>>>end》》》 signallingInfo: {}",firstRetainData.length,rate,groupCount,signallingInfo.toStringPart());
		
		// 分组推送出去
		if(firstGroupBuffer!=null) {
		for (int i = 0; i < groupCount; i++) {
			pushBufferData(firstGroupBuffer[i],i);
		}
		
		}
	}
	private void pushBufferData(byte[] firstBuffer,int count) {
		log.debug("pushBufferData 推送识别 {}    ----------------------------->>>> 目的IP: {}     rate: {}, buffer:{} ",count,signallingInfo.getClientIP(),rate,firstBuffer.length*2);
		Map<String, Object> product=null;
		if(pushSeesionId==null) {
			pushSeesionId=CaptureNetPacketService.getIatConfig().iatOnlineBegin(rate,signallingInfo);
			if(pushSeesionId!=null) {
//				WavFileUtil.mergeWaveData(wavFileInfo, firstRealTimeData, reverseRealTimeData,null);
//				product=CaptureNetPacketService.getIflytekConfig().iatOnlineWrite(pushSeesionId,WavFileUtil.convertG711ToPcm(firstBuffer, null),1);
				product=CaptureNetPacketService.getIatConfig().iatOnlineWrite(pushSeesionId,firstBuffer,1,signallingInfo);
			}
		}else {
//			product=CaptureNetPacketService.getIflytekConfig().iatOnlineWrite(pushSeesionId,WavFileUtil.convertG711ToPcm(firstBuffer, null),2);
			product=CaptureNetPacketService.getIatConfig().iatOnlineWrite(pushSeesionId,firstBuffer,2,signallingInfo);
		}
		
		if(product!=null ) {
			if(product.get("result")!=null)
				if( product.get("result").toString().length()>0)
			{
			product.put("deviceNumber", deviceInfo.getDeviceNumber());
			product.put("type", "voiceAssistant");
			product.put("timestamp", new Date().getTime());
			RedisConfig.publishMessage("VoiceAssistant",product);
			RedisConfig.publishRecQueueMessage("VoiceAssistant:"+deviceInfo.getDeviceNumber(),product);
			RedisConfig2.publishMessage("VoiceAssistant",product);
			RedisConfig2.publishRecQueueMessage("VoiceAssistant:"+deviceInfo.getDeviceNumber(),product);
			}
		}
		
	}
	
	
 
	
	
	
	/**
	 * 添加语音数据
	 */
	public void appendVoiceData(){
		if(positiveRealTimeData ==null )return ;
//		log.debug("正在添加实时数据去推送.目的IP:{} 正向大小：  {} ",signallingInfo.getClientIP(),firstRealTimeData.length);
		synchronized (lockObj) {
			if(positiveRetainData ==null) {
				positiveRetainData = positiveRealTimeData.clone();
//				reverseRetainData=reverseRealTimeData.clone();
			}
			else {
				
				if(positiveRetainData.length>CaptureNetPacketService.getAppConfig().getRealTimeMaxRetainData())
				{
					//保留区已经大于一定的量，再送过去翻译已经无意义。已经属于延迟了，8000大概是1秒的。必须大于2秒，16000
					positiveRetainData = positiveRealTimeData.clone();
				}
				else 
					positiveRetainData =Tools.byteMerger(positiveRetainData, positiveRealTimeData);
//				reverseRetainData=Tools.byteMerger(reverseRetainData, reverseRealTimeData);
			}
		}
		 
		log.debug("实时发送区大小....  sessionid: {} DeviceNumber: {} 目的IP:{} 正向大小：  {} 反向 大小： {}",pushSeesionId,deviceInfo.getDeviceNumber(),signallingInfo.getClientIP(), positiveRetainData.length, positiveRetainData.length);
	}
	
	 
	
	
	
	//测试存为文件
	private void testSaveData() {
		if(positiveRealTimeData ==null)return ;
		log.debug("VoiceInfoPush sendData -----------------------------------------------------》》》 signallingInfo: {}",signallingInfo.toStringPart());
		StringBuffer path=new StringBuffer(signallingInfo.getRecordPath());
		path.insert(signallingInfo.getRecordPath().length()-4, "test");
//		WavFileUtil.mergeWaveData(wavFileInfo, firstRealTimeData, reverseRealTimeData, path.toString());
		positiveRealTimeData =null;
	}

	private void initAnalysis() {
			log.debug("----------------->>>>>VoiceInfoPush initAnalysis uuid: {},signallingInfo: {}",signallingInfo.getCallUUID(),signallingInfo.toStringPart());
	}
	 /**
	  * 
	 	* <strong>Title: 发包大小的速率<strong>
	 	* <p>Description: 控制发包的速率，为8000倍数，一般8000/16000，默认值:8000<p>
	 	* <p>Company: </p> 
	 	*<strong>Copyright:</strong> Copyright (c) 2019
	 	* @version: 1.0
	 	* @author  ASUS:augustWei
	 	* @date  2021 下午4:06:27
	 	* @param byteRate
	  */
	
	 public static void setRate(int byteRate){
		 rate=byteRate;
	 }
	 
}
